package com.stars.pao.aicloud.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stars.pao.aicloud.config.ThreadPoolConfig;
import com.stars.pao.aicloud.entity.Discuss;
import com.stars.pao.aicloud.entity.DiscussSupport;
import com.stars.pao.aicloud.entity.User;
import com.stars.pao.aicloud.entity.vo.CommentVO;
import com.stars.pao.aicloud.entity.vo.DiscussVO;
import com.stars.pao.aicloud.service.ICommentService;
import com.stars.pao.aicloud.service.IDiscussService;
import com.stars.pao.aicloud.service.IDiscussSupportService;
import com.stars.pao.aicloud.service.IUserService;
import com.stars.pao.aicloud.util.AppVariable;
import com.stars.pao.aicloud.util.ResponseEntity;
import com.stars.pao.aicloud.util.SecurityUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Tag(name = "讨论控制器")
// 讨论
@RestController
@RequestMapping("/discuss")
public class DiscussController {
    @Resource
    private IDiscussService discussService;
    @Resource
    private ThreadPoolTaskExecutor threadPool;
    @Resource
    private IUserService userService;
    @Resource
    private ICommentService commentService;
    @Resource
    private KafkaTemplate kafkaTemplate;
    @Resource
    private IDiscussSupportService discussSupportService;


    // 讨论详情显示
    @PostMapping("/detail")
    public ResponseEntity detail(Long did) throws ExecutionException, InterruptedException {
        // 判断did
        if(did == null || did <= 0) {
            return ResponseEntity.fail("参数错误");
        }
        Discuss discuss = discussService.getById(did);
//      判断讨论是否存在
        if(discuss != null && discuss.getDid() > 0) {
//            阅读量+1操作
            threadPool.submit(()->{
//              1.更新数据
                discussService.lambdaUpdate().eq(Discuss::getDid, did).set(Discuss::getReadcount, discuss.getReadcount() + 1).update();
//              2.返回的对象阅读数+1
                discuss.setReadcount(discuss.getReadcount() + 1);
            });


//            任务1： 查询 discuss 中的 username
            CompletableFuture<DiscussVO> task1 = CompletableFuture.supplyAsync(() -> {
//                利用 hutool 的工具 将 Discuss 转换为 DiscussVO
                DiscussVO discussVO = BeanUtil.toBean(discuss, DiscussVO.class);
                User user = userService.getById(discuss.getUid());
                if(user != null && user.getUid() > 0) {
                    discussVO.setUsername(user.getUsername());
                }
                return discussVO;
            }, threadPool);

//            任务2： 查询 discuss 所对应 的 comment 列表
            CompletableFuture<List<CommentVO>> task2 = CompletableFuture.supplyAsync(() -> {
                return commentService.getCommentList(did);
            },threadPool);
//            任务编排
            CompletableFuture.allOf(task1, task2);
            Map<String, Object> result = new HashMap<>();
            result.put("discuss", task1.get());
            result.put("commentList", task2.get());
            return ResponseEntity.succ(result);
        }
        return ResponseEntity.fail("该话题不存在");
    }


    // 话题添加功能
    @PostMapping("/add")
    public ResponseEntity add(@Validated Discuss discuss){
        discuss.setUid(SecurityUtil.getCurrentUser().getUid());
        boolean addResult = discussService.save(discuss);
        if(!addResult) {
//            添加失败
            return ResponseEntity.fail("数据保存失败，请重试");
        }
        return ResponseEntity.succ(addResult);

    }

    // 展示我的话题显示
    @PostMapping("/getMyList")
    public ResponseEntity getMyList(){
        return ResponseEntity.succ(discussService.list(
                Wrappers.lambdaQuery(Discuss.class)
                        .eq(Discuss::getUid, SecurityUtil.getCurrentUser().getUid())
                        .orderByDesc(Discuss::getDid)
        ));
    }

    // 分页展示话题列表
    @PostMapping("/list")
    public ResponseEntity list(Integer page, Integer type){
        // 1 = 点赞推荐来的推荐 2 = 时间可优化为did最新
        if(page <= 0 || page == null) {
            page = 1;
        }
        if(type == null || type <= 0) {
            type = 1;
        }
        QueryWrapper<Discuss> queryWrapper = new QueryWrapper<>();
        if(type == 1) {
            // 按照点赞数排序 点赞数字段建立建立索引提高效率
            queryWrapper.orderByDesc("supportcount");
        } else {
            // 按照时间排序
            queryWrapper.orderByDesc("did");
        }
        Page<Discuss> result = discussService.page(new Page<>(page, AppVariable.PAGE_SIZE),
                queryWrapper);
        return ResponseEntity.succ(result);
    }

    // 删除话题
    @PostMapping("/delete")
    public ResponseEntity delete(Long did){
        if(did == null || did <= 0) {
            return ResponseEntity.fail("参数错误");
        }

        boolean exist = discussService.remove(Wrappers.lambdaQuery(Discuss.class)
                .eq(Discuss::getDid, did)
                .eq(Discuss::getUid, SecurityUtil.getCurrentUser().getUid()));
        if(!exist) {
            return ResponseEntity.fail("话题不存在");
        }
        return ResponseEntity.succ(exist);
    }

    // 讨论表点赞事件
    @PostMapping("/support")
    public ResponseEntity support(Long did){
        if(did == null || did <= 0) {
            return ResponseEntity.fail("参数错误");
        }
        kafkaTemplate.send(AppVariable.DISCUSS_SUPPORT_TOPIC,did+"_"+
                SecurityUtil.getCurrentUser().getUid());
        return ResponseEntity.succ(true);
    }
    

    // 监听事件 —— kafka 点赞事件
    @KafkaListener(topics = AppVariable.DISCUSS_SUPPORT_TOPIC)
    public void listen(String message, Acknowledgment ack) {
        String[] split = message.split("_");
        Long did = Long.parseLong(split[0]);
        Long uid = Long.parseLong(split[1]);
        // 1.判断当前用户是否给这个讨论点赞过
        List<DiscussSupport> list = discussSupportService.list(Wrappers.lambdaQuery(DiscussSupport.class)
                .eq(DiscussSupport::getDid, did)
                .eq(DiscussSupport::getUid, uid)
        );
        if(list.size() == 0 || list == null) {
            // 2.修改表的点赞总数
            boolean ret = discussService.lambdaUpdate().eq(Discuss::getDid, did).set(Discuss::getSupportcount,
                    discussService.getById(did).getSupportcount() + 1).update();
            // 3.添加点赞记录
            if(ret) {
                DiscussSupport discussSupport = new DiscussSupport();
                discussSupport.setDid(did);
                discussSupport.setUid(uid);
                discussSupportService.save(discussSupport);
            }
        }
        // 4.手动确认消息 避免消息积压
        ack.acknowledge();
    }
}
